// POH Insert module
module OH_PINS(
   RESET,
   TCLK_155M,

   MPI_TPOH_J1,
   MPI_TPOH_C2,
   MPI_TPOH_G1,
   MPI_TPOH_F2,
   MPI_TPOH_H4,
   MPI_TPOH_F3,
   MPI_TPOH_K2,
   MPI_TPOH_N1,
   PMON_REI_CNT,

   DBIN_TDATA,
   DBIN_FCNT8,
   DBIN_FCNT270,
   DBIN_FCNT9,
   DBIN_MFCNT64,
   DBIN_PINS_BYPASS,

   DBOUT_TDATA,
   DBOUT_FCNT8,
   DBOUT_FCNT270,
   DBOUT_FCNT9,
   DBOUT_MFCNT64
   );

input              RESET;
input              TCLK_155M;

input[511:0]       MPI_TPOH_J1;
input[7:0]         MPI_TPOH_C2;
input[7:0]         MPI_TPOH_G1;
input[7:0]         MPI_TPOH_F2;
input[7:0]         MPI_TPOH_H4;
input[7:0]         MPI_TPOH_F3;
input[7:0]         MPI_TPOH_K2;
input[7:0]         MPI_TPOH_N1;
input[3:0]         PMON_REI_CNT;

input[63:0]        DBIN_TDATA;
input[2:0]         DBIN_FCNT8;
input[8:0]         DBIN_FCNT270;
input[3:0]         DBIN_FCNT9;
input[5:0]         DBIN_MFCNT64;
input              DBIN_PINS_BYPASS;

output[63:0]       DBOUT_TDATA;
output[2:0]        DBOUT_FCNT8;
output[8:0]        DBOUT_FCNT270;
output[3:0]        DBOUT_FCNT9;
output[5:0]        DBOUT_MFCNT64;


reg[7:0]           VCINS_TPOH_J1;
reg[3:0]           VCINS_REI_ME1, VCINS_REI_ME2;
reg[3:0]           VCINS_REI;
reg[63:0]          VCINS_TDATA;
reg[2:0]           VCINS_FCNT8;
reg[8:0]           VCINS_FCNT270;
reg[3:0]           VCINS_FCNT9;
reg[5:0]           VCINS_MFCNT64;


reg                B3_PLOAD_EN;
reg                B3_END_FRAME;
reg[7:0]           B3_CALC_REGS;
reg[7:0]           B3_TPOH_B3;



//****** CONTINUOUS VC4 CONCATENATION OVERHEAD INSERT   *******//
always @( DBIN_MFCNT64 or MPI_TPOH_J1) begin
   case ( DBIN_MFCNT64[5:0] )
   6'h00:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*0+7:8*0];
   6'h01:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*1+7:8*1];
   6'h02:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*2+7:8*2];
   6'h03:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*3+7:8*3];
   6'h04:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*4+7:8*4];
   6'h05:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*5+7:8*5];
   6'h06:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*6+7:8*6];
   6'h07:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*7+7:8*7];
   6'h08:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*8+7:8*8];
   6'h09:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*9+7:8*9];
   6'h0A:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*10+7:8*10];
   6'h0B:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*11+7:8*11];
   6'h0C:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*12+7:8*12];
   6'h0D:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*13+7:8*13];
   6'h0E:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*14+7:8*14];
   6'h0F:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*15+7:8*15];

   6'h10:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*16+7:8*16];
   6'h11:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*17+7:8*17];
   6'h12:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*18+7:8*18];
   6'h13:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*19+7:8*19];
   6'h14:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*20+7:8*20];
   6'h15:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*21+7:8*21];
   6'h16:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*22+7:8*22];
   6'h17:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*23+7:8*23];
   6'h18:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*24+7:8*24];
   6'h19:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*25+7:8*25];
   6'h1A:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*26+7:8*26];
   6'h1B:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*27+7:8*27];
   6'h1C:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*28+7:8*28];
   6'h1D:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*29+7:8*29];
   6'h1E:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*30+7:8*30];
   6'h1F:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*31+7:8*31];

   6'h20:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*32+7:8*32];
   6'h21:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*33+7:8*33];
   6'h22:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*34+7:8*34];
   6'h23:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*35+7:8*35];
   6'h24:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*36+7:8*36];
   6'h25:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*37+7:8*37];
   6'h26:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*38+7:8*38];
   6'h27:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*39+7:8*39];
   6'h28:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*40+7:8*40];
   6'h29:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*41+7:8*41];
   6'h2A:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*42+7:8*42];
   6'h2B:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*43+7:8*43];
   6'h2C:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*44+7:8*44];
   6'h2D:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*45+7:8*45];
   6'h2E:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*46+7:8*46];
   6'h2F:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*47+7:8*47];

   6'h30:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*48+7:8*48];
   6'h31:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*49+7:8*49];
   6'h32:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*50+7:8*50];
   6'h33:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*51+7:8*51];
   6'h34:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*52+7:8*52];
   6'h35:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*53+7:8*53];
   6'h36:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*54+7:8*54];
   6'h37:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*55+7:8*55];
   6'h38:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*56+7:8*56];
   6'h39:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*57+7:8*57];
   6'h3A:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*58+7:8*58];
   6'h3B:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*59+7:8*59];
   6'h3C:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*60+7:8*60];
   6'h3D:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*61+7:8*61];
   6'h3E:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*62+7:8*62];
   6'h3F:     VCINS_TPOH_J1[7:0]   <= MPI_TPOH_J1[8*63+7:8*63];
   default:   VCINS_TPOH_J1[7:0]   <= 8'h00;
   endcase
end

always @(posedge RESET or posedge TCLK_155M) begin
   if ( RESET==1'b1 ) begin
      VCINS_REI_ME1[3:0]           <= 4'd0;
      VCINS_REI_ME2[3:0]           <= 4'd0;
   end
   else begin
      VCINS_REI_ME1[3:0]           <= PMON_REI_CNT[3:0];
      VCINS_REI_ME2[3:0]           <= VCINS_REI_ME1[3:0];
   end
end
always @(posedge RESET or posedge TCLK_155M) begin
   if ( RESET==1'b1 )
      VCINS_REI[3:0]               <= 4'd0;
   else begin
      if ( VCINS_REI_ME1[3:0]==VCINS_REI_ME2[3:0])
         VCINS_REI[3:0]            <= VCINS_REI_ME2[3:0];
   end
end

always @(posedge RESET or posedge TCLK_155M) begin
   if ( RESET==1'b1 )
      VCINS_TDATA[63:0]            <= 64'd0;
   else begin
      if ( DBIN_PINS_BYPASS==1'b0 ) begin                                   // DDV
         if ( DBIN_FCNT270[8:0]==9'd9 && DBIN_FCNT8[2:0]==3'd0 ) begin
            VCINS_TDATA[55:0]         <= 56'd0;   // set R bits to 0
            case ( DBIN_FCNT9[3:0] )
            4'b0000    :      VCINS_TDATA[63:56]         <= VCINS_TPOH_J1[7:0];
            4'b0001    :      VCINS_TDATA[63:56]         <= B3_TPOH_B3[7:0];
            4'b0010    :      VCINS_TDATA[63:56]         <= MPI_TPOH_C2[7:0];
            4'b0011    :      VCINS_TDATA[63:56]         <= {VCINS_REI[3:0], MPI_TPOH_G1[3:0]};
            4'b0100    :      VCINS_TDATA[63:56]         <= MPI_TPOH_F2[7:0];
            4'b0101    :      VCINS_TDATA[63:56]         <= MPI_TPOH_H4[7:0];
            4'b0110    :      VCINS_TDATA[63:56]         <= MPI_TPOH_F3[7:0];
            4'b0111    :      VCINS_TDATA[63:56]         <= MPI_TPOH_K2[7:0];
            4'b1000    :      VCINS_TDATA[63:56]         <= MPI_TPOH_N1[7:0];
            default    :      VCINS_TDATA[63:56]         <= 8'd0;
            endcase
         end
         else if ( DBIN_FCNT270[8:0]==9'd9 && DBIN_FCNT8[2:0]!=3'd0) begin
                              VCINS_TDATA[63:0]          <= 64'd0;
         end
         else begin
                              VCINS_TDATA[63:0]          <= DBIN_TDATA[63:0];
         end
      end
      else begin
                              VCINS_TDATA[63:0]          <= DBIN_TDATA[63:0];
      end
   end
end

always @(posedge RESET or posedge TCLK_155M) begin
   if ( RESET==1'b1 ) begin
      VCINS_FCNT8[2:0]             <= 3'd0;
      VCINS_FCNT270[8:0]           <= 9'd0;
      VCINS_FCNT9[3:0]             <= 4'd0;
      VCINS_MFCNT64[5:0]           <= 6'd0;
   end
   else begin
      VCINS_FCNT8[2:0]             <= DBIN_FCNT8[2:0];
      VCINS_FCNT270[8:0]           <= DBIN_FCNT270[8:0];
      VCINS_FCNT9[3:0]             <= DBIN_FCNT9[3:0];
      VCINS_MFCNT64[5:0]           <= DBIN_MFCNT64[5:0];
   end
end
   assign DBOUT_TDATA[63:0]   =VCINS_TDATA[63:0];
   assign DBOUT_FCNT8[2:0]    =VCINS_FCNT8[2:0];
   assign DBOUT_FCNT270[8:0]  =VCINS_FCNT270[8:0];
   assign DBOUT_FCNT9[3:0]    =VCINS_FCNT9[3:0];
   assign DBOUT_MFCNT64[5:0]  =VCINS_MFCNT64[5:0];



//****** B3 calculate, calculate B3 from all data and capture result at the end of frame  ******//
always @( VCINS_FCNT270 ) begin
   if ( VCINS_FCNT270[8:0]<9'd9 )
      B3_PLOAD_EN                  <= 1'b0;
   else
      B3_PLOAD_EN                  <= 1'b1;
end
always @( VCINS_FCNT270 or VCINS_FCNT9 or VCINS_FCNT8) begin
   if ( VCINS_FCNT270[8:0]==9'd269 && VCINS_FCNT9[3:0]==4'd8 && VCINS_FCNT8[2:0]==3'd7 )
      B3_END_FRAME                 <= 1'b1;
   else
      B3_END_FRAME                 <= 1'b0;
end


always @(posedge RESET or posedge TCLK_155M) begin
   if ( RESET==1'b1 ) begin
      B3_CALC_REGS[7:0]            <= 8'd0;
      B3_TPOH_B3[7:0]              <= 8'd0;
   end
   else begin
      if ( B3_PLOAD_EN==1'b1 ) begin
         if ( B3_END_FRAME==1'b1 ) begin
            B3_CALC_REGS[7:0]      <= 8'd0;
            B3_TPOH_B3[7:0]        <= B3_CALC_REGS[7:0] ^ VCINS_TDATA[7:0]   ^ VCINS_TDATA[15:8]  ^ VCINS_TDATA[23:16] ^ VCINS_TDATA[31:24] ^ VCINS_TDATA[39:32] ^ VCINS_TDATA[47:40] ^ VCINS_TDATA[55:48] ^ VCINS_TDATA[63:56];
         end
         else begin
            B3_CALC_REGS[7:0]      <= B3_CALC_REGS[7:0] ^ VCINS_TDATA[7:0]   ^ VCINS_TDATA[15:8]  ^ VCINS_TDATA[23:16] ^ VCINS_TDATA[31:24] ^ VCINS_TDATA[39:32] ^ VCINS_TDATA[47:40] ^ VCINS_TDATA[55:48] ^ VCINS_TDATA[63:56];
         end
      end
   end
end

endmodule